//  Created by <Omar MALAGOUEN>

//  Copyright 2011 All rights reserved.
//

/*
 * Various utilities for command line tools
 * Copyright (c) 2000-2010 Omar Malagouen
 *
 * This file is part of Kakola.
 *
 * Kakola is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * Kakola is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with Kakola; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "coptions.h"
#include "common.h"
#include "ui_coptions.h"

COptions::COptions(QWidget *parent) :
        QDialog(parent)
        ,m_ui(new Ui::COptions)
{
    QIcon  windowIcon;
    settings = new QSettings(QSettings::NativeFormat,QSettings::UserScope,QCoreApplication::organizationName(),QCoreApplication::applicationName());
    qDebug("Configuration file = %s",settings->fileName().toLatin1().data());
    langueIndex=0;
    init = 0;
    this->systemNumberOfCPU = 1;
    windowIcon.addPixmap(QPixmap(QString::fromUtf8(":/resources/icons/options.png")), QIcon::Normal, QIcon::Off);
    m_ui->setupUi(this);
    m_ui->spinBoxCPU->setMaximum(MAXCPU);
    m_ui->spinBoxCPU->setMinimum(1);
    this->setWindowTitle(tr("Set default settings"));
    this->setWindowIcon(windowIcon);


    // Language definition
    optionListProfileInCombo = new QListWidget ;


    QString  translateDir = settings->value("translateDir").toString();
    QDir translateQDir(translateDir) ;
    QStringList filters_qm;
    filters_qm << "*.qm" ;
    translateQDir.setNameFilters(filters_qm);
    QStringList listTranslationFile = translateQDir.entryList(QDir::Files | QDir::NoDotAndDotDot);


    m_ui->langueComboBox->addItem(QPixmap(QString::fromUtf8(":/resources/icons/English.png")),"English");

    foreach(QString s, listTranslationFile){
        qDebug("** Translation file : %s",s.toLatin1().data());
        s.replace("kakola_","");
        s.replace(".qm","");
        QString r = ":/resources/icons/" + s + ".png";
        m_ui->langueComboBox->addItem(QPixmap(QString::fromUtf8(r.toLatin1().data())),
                                      s.toLatin1().data());
    }

    language = settings->value("language").toString();
    langueIndex= 0;
    m_ui->langueComboBox->setCurrentIndex(0);


    ffmpeg = settings->value("ffmpeg").toString();
    mencoder = settings->value("mencoder").toString();
    m_ui->lineFFMpegProgram->setText(ffmpeg);
    m_ui->lineMencoderProgram->setText(mencoder);

    if (settings->value("overwrite").toString() == "yes")
    {
        m_ui->checkBoxOverwriteFile->setChecked(true);
        this->overwrite = "yes";
    }
    else
        this->overwrite = "no";


    numberOfCPUToUse = settings->value("numberCPU").toInt();
    if (numberOfCPUToUse == 0)
        numberOfCPUToUse = 2;
    defaultProfile = settings->value("defaultProfile").toString();

    initEnvironnementVariable();
}

COptions::~COptions()
{

    foreach( QString key, hashProfileGroup.keys() )
    {
        foreach(CProfile *pf, hashProfileGroup[key]){
            //qDebug("Delete memory profile %s",pf->filename.toLatin1().data());
            delete pf;
        }
    }


    while (optionListProfileInCombo->count() != 0)
    {
        delete optionListProfileInCombo->takeItem(0);
        this->optionListProfileInCombo->removeItemWidget(optionListProfileInCombo->takeItem(0));
    }

    delete m_ui;
    delete settings;
}

void COptions::printOptionsValue(){

    if (this->mencoder == ""){
        settings->setValue("ffmpeg",ffmpeg);
        m_ui->lineFFMpegProgram->setText("ffmpeg");
        ffmpeg = "ffmpeg";
    }

    if (this->mencoder == "")
    {
        settings->setValue("mencoder",mencoder);
        m_ui->lineMencoderProgram->setText("mencoder");
        mencoder = "mencoder";
    }

    this->destinationDirectory = settings->value("destinationDirectory").toString();
    m_ui->lineEditDestdir->setText(this->destinationDirectory);

    this->ffmpeg = settings->value("ffmpeg").toString();
    m_ui->lineFFMpegProgram->setText(this->ffmpeg);
    this->ffmpeg = settings->value("ffmpeg").toString();
    m_ui->lineMencoderProgram->setText(this->mencoder);
    this->mencoder = settings->value("mencoder").toString();

    qDebug("Using program ffmpeg : %s",this->ffmpeg.toLatin1().data());
    qDebug("Using program mencoder : %s",this->mencoder.toLatin1().data());
    qDebug("Destination directory=%s",settings->value("destinationDirectory").toString().toLatin1().data());

    this->language = settings->value("language").toString();

    //qDebug("numberCPU=%s",settings->value("numberCPU").toString().toLatin1().data());
    this->numberOfCPUToUse = settings->value("numberCPU").toInt();

    //qDebug("lastDirectory=%s",settings->value("lastDirectory").toString().toLatin1().data());
    this->lastDirectory = settings->value("lastDirectory").toString();

    //qDebug("defaultProfile=%s",settings->value("defaultProfile").toString().toLatin1().data());
    this->defaultProfile = settings->value("defaultProfile").toString();

    //qDebug("defaultProfileDescr=%s",settings->value("defaultProfileDescr").toString().toLatin1().data());
    this->defaultProfileDescr = settings->value("defaultProfileDescr").toString();

    //qDebug("langueIndex=%d",this->langueIndex);
    //qDebug("indexOfDefaultProfileInComboBox=%d",this->getIndexOfDefaultProfileInComboBox());
}


void COptions::showDialog(){
    printOptionsValue();
    m_ui->defaultProfileComboBox->setCurrentIndex(getIndexOfDefaultProfileInComboBox());
    this->exec();
    printOptionsValue();
}

void COptions::changeEvent(QEvent *e)
{
    QDialog::changeEvent(e);
    m_ui->lineFFMpegProgram->setText(this->ffmpeg);
    m_ui->lineMencoderProgram->setText(this->mencoder);
    m_ui->lineEditDestdir->setText(this->destinationDirectory);
    m_ui->lineEditLastDir->setText(this->lastDirectory);
    m_ui->spinBoxCPU->setValue(this->numberOfCPUToUse);

    int index = m_ui->langueComboBox->findText(settings->value("language").toString());
    if (index != -1)
        m_ui->langueComboBox->setCurrentIndex(index);
    else
        m_ui->langueComboBox->setCurrentIndex(index);

    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void COptions::on_pushButtonCancel_clicked()
{
    this->close();
}

void COptions::on_toolButtonChoisir_clicked()
{
    QString dest = QFileDialog::getExistingDirectory(this);
    m_ui->lineEditDestdir->setText(dest);
}

void COptions::on_toolButtonChoisir_2_clicked()
{
#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64)
    QString p = "C:/Program Files/";
#elif defined(Q_OS_MACX)
    QString p = "/usr/bin/";
#else
    QString p = "/usr/bin/";
#endif
    QString program = QFileDialog::getOpenFileName(this, tr("Choose ffmpeg program"),
                                                   p,tr("*"));
    m_ui->lineFFMpegProgram->setText(program);
}


void COptions::on_pushButtonApply_clicked()
{
    qDebug("Writting options to file %s",settings->fileName().toLatin1().data());
    ;
    settings->setValue("destinationDirectory",QDir::cleanPath(m_ui->lineEditDestdir->text()));
    settings->setValue("ffmpeg",QDir::cleanPath(m_ui->lineFFMpegProgram->text()));
    settings->setValue("mencoder",QDir::cleanPath(m_ui->lineMencoderProgram->text()));
    settings->setValue("language",m_ui->langueComboBox->itemText(langueIndex));
    settings->setValue("numberCPU",QString::number( m_ui->spinBoxCPU->value(),10));
    settings->setValue("lastDirectory",QDir::cleanPath(m_ui->lineEditLastDir->text()));
    settings->setValue("defaultProfile",this->getProfileAt(m_ui->defaultProfileComboBox->currentIndex())->filename);
    settings->setValue("defaultProfileDescr",this->getProfileAt(m_ui->defaultProfileComboBox->currentIndex())->description);

    if (m_ui->checkBoxOverwriteFile->isChecked())
        settings->setValue("overwrite","yes");
    else
        settings->setValue("overwrite","no");

    settings->sync();
    this->printOptionsValue();
    this->close();
}

void COptions::initEnvironnementVariable(){
#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64)
    qDebug("System : WIN32");
    userName = QString(getenv("USERNAME"));
    system = "WIN32";
    bool b = false;
    systemNumberOfCPU = QString(getenv("NUMBER_OF_PROCESSORS")).toInt(&b,10);
    if ( b == false) systemNumberOfCPU =  1;

    arch = QString(getenv("PROCESSOR_ARCHITECTURE"));
    profileDir = QString(getenv("USERPROFILE"));
    tmpDir = QString(getenv("TMP"));
    homeDir = profileDir;
    homeDrive = QString(getenv("HOMEDRIVE"));
    homeDir = profileDir;

#elif defined(Q_OS_MACX)
    qDebug("System : Mac OS X");
    homeDir = QString(getenv("HOME"));
    tmpDir = "/tmp/";
    system = "MACX";
#else
    qDebug("System : Linux");
    homeDir = QString(getenv("HOME"));
    tmpDir = "/tmp/";
    system = "LINUX";
#endif

    tmpDir = this->settings->value("tmpDir",tmpDir).toString();
    tmpDir = QDir::cleanPath(tmpDir);
    qDebug("Tempory directory = %s",this->tmpDir.toLatin1().data());

    applicationDir = homeDir + "/." + QCoreApplication::applicationName();
    profileDir = homeDir + getProfileDir();
    destinationDirectory = homeDir + "/" + QCoreApplication::applicationName()+"-Videos";

    settings->setValue("tmpDir",tmpDir);

    if ( settings->value("destinationDirectory").toString() == "")
        settings->setValue("destinationDirectory",QDir::cleanPath(destinationDirectory));

    if (settings->value("ffmpeg").toString() == ""){
        settings->setValue("ffmpeg",ffmpeg);
        m_ui->lineFFMpegProgram->setText("ffmpeg");
    }
    if (m_ui->lineMencoderProgram->text() == "")
    {
        settings->setValue("mencoder",mencoder);
        m_ui->lineMencoderProgram->setText("mencoder");
    }
    createDirectory(applicationDir);
    createDirectory(profileDir);

    this->getListProfileFile(profileDir);

    return ;
}

bool COptions::createDirectory(QString dir){

    QDir profileQDir(dir);

    if ( ! profileQDir.exists()){
        if ( profileQDir.mkdir(dir) == false )
            qDebug("directory %s doest not exist, error whil creating directory",dir.toLatin1().data());
        return false;
    }

    return true;
}

int COptions::getIndexOfDefaultProfileInComboBox(){
    return getIndexOfProfileInComboBox(this->profileDir, this->defaultProfile);
}

int COptions::getIndexOfProfileInComboBox(QString profileDirName,QString profileFileName){
    int found = 0;
    foreach( QString key, hashProfileGroup.keys() )
    {
        found++;
        foreach(CProfile *pf, hashProfileGroup[key]){
            if (QDir::cleanPath(pf->filename) == QDir::cleanPath(profileFileName) &&
                QDir::cleanPath(pf->dirname) == QDir::cleanPath(profileDirName) ){
                qDebug("Profile found : Index of profile %s/%s is %d",profileDirName.toLatin1().data(),
                       profileFileName.toLatin1().data(),found);
                return found;
            }
            found++;
        }
    }
    qDebug("Profile not found : Index of profile %s is %d",profileFileName.toLatin1().data(),found);
    return found;
}

int COptions::indexOfCProfile(CProfile *p){
    int found = 0;
    QString l_filename;
    foreach( QString key, hashProfileGroup.keys() )
    {
        found++;
        foreach(CProfile *pf, hashProfileGroup[key]){
            if (pf == p){
                qDebug("Found OK index of profile %s is %d",pf->filename.toLatin1().data(),found);
                return found;
            }
            found++;
            l_filename = QDir::cleanPath(pf->filename);
        }
    }
    qDebug("ERROR Found KO index of profile %s use %d",l_filename.toLatin1().data(),found);
    return found;
}

CProfile* COptions::getProfileAt(int i){
    int found = 0;
    QString l_filename;
    CProfile *pf = NULL;
    foreach( QString key, hashProfileGroup.keys() )
    {
        found++;
        foreach(pf, hashProfileGroup[key]){
            if (i == found){
                //qDebug("Found OK profile %d is %s",found,pf->filename.toLatin1().data());
                return pf;
            }
            found++;
            l_filename = QDir::cleanPath(pf->filename);
        }
    }
    qDebug("ERROR Found KO no profile found at %d use %s",found,l_filename.toLatin1().data());
    return pf;
}


//TODO
void COptions::appendToProfileCombo(QString p){
    m_ui->defaultProfileComboBox->addItem(p);
}
//TODO
void COptions::updateProfileCombo(int i, QString p){
    m_ui->defaultProfileComboBox->setEditable(true);
    m_ui->defaultProfileComboBox->setItemText(i,p);
    m_ui->defaultProfileComboBox->setEditable(true);
}

void COptions::on_langueComboBox_activated(int index)
{
    langueIndex=index;
}

void COptions::getListProfileFile(QString directory){
    if (directory == "")
        directory = this->profileDir;
    QDir dir( directory );

    QStringList filters;
    filters << "*.profile";
    dir.setNameFilters(filters);
    QStringList fichiers = dir.entryList( QDir::Files | QDir::NoDotAndDotDot );

    if (fichiers.empty())
    {
        QMessageBox msgBox;
        QString sText = "No profiles in directory " + profileDir + " ! Must quit";
        msgBox.setInformativeText(sText);
        msgBox.show();
    }

    hashProfileGroup.clear();

    if (this->init == 0)
        foreach(QString oneFile,fichiers){

        CProfile *oneProfile = new CProfile;

        QSettings settingsProfile(directory+"/"+oneFile,QSettings::IniFormat,this);

        oneProfile->description = settingsProfile.value("description").toString();
        oneProfile->extension = settingsProfile.value("extension").toString();

        oneProfile->outputDir = settingsProfile.value("outputDir").toString();
        oneProfile->prefix = settingsProfile.value("prefix").toString();
        oneProfile->suffix = settingsProfile.value("suffix").toString();
        oneProfile->popupDone = settingsProfile.value("popupDone").toString();
        oneProfile->popupDoneMsg = settingsProfile.value("popupDoneMsg",tr("Encoding ended successfully !")).toString();

        int j = 0;
        QString str_pg = "program[0]";
        while(settingsProfile.value(str_pg).toString() != "")
        {
            oneProfile->program[j] = settingsProfile.value(str_pg).toString();
            j++;
            str_pg = "program[" + QString::number(j,10) + "]";
        }

        bool b;
        oneProfile->coef = settingsProfile.value("coef","100").toInt(&b);
        oneProfile->group = settingsProfile.value("group").toString();
        oneProfile->filename = QDir::cleanPath(oneFile);
        oneProfile->dirname = QDir::cleanPath(directory);


        int i = 0;
        QString str = "cmd[0]";
        oneProfile->listCommand.clear();
        oneProfile->listCommand.append(new QString(settingsProfile.value(str,"ERROR_NO_COMMAND_DEFINED").toString()));
        i= 1;
        str = "cmd[1]";
        while(settingsProfile.value(str).toString() != "")
        {
            oneProfile->listCommand.append(new QString(settingsProfile.value(str).toString()));
            i++;
            str = "cmd[" + QString::number(i,10) + "]";
        }


        if (oneProfile->outputDir == "")
            oneProfile->outputDir = settings->value("destinationDirectory").toString();



        if (oneProfile->group == "")
        {
            oneProfile->group = QString("Other");
            settingsProfile.setValue("group","Other");
            settingsProfile.sync();
        }

        hashProfileGroup[oneProfile->group].append(oneProfile);
        if (this->defaultProfile == "")
        {
            this->defaultProfile = oneProfile->filename;
            this->settings->setValue("defaultProfile",this->defaultProfile);
            this->settings->sync();
        }

    }
    this->init = 1;


    this->populateComboBox(m_ui->defaultProfileComboBox,
                           this->profileDir,
                           this->defaultProfile,
                           this->optionListProfileInCombo,
                           this->profileDir,
                           this->defaultProfile);

    return ;
}

void COptions::on_toolButtonChoisir_mencoder_clicked()
{
#if defined(Q_OS_WIN32) || defined(Q_OS_WIN64)
    QString p = "C:/Program Files/";
#elif defined(Q_OS_MACX)
    QString p = "/usr/bin/";
#else
    QString p = "/usr/bin/";
#endif
    QString program = QFileDialog::getOpenFileName(this, tr("Choose Mencoder program"),
                                                   p,tr("*"));
    m_ui->lineMencoderProgram->setText(program);
}

// return the index of the profile profilename in the combobox and build the combo with data of hashProfileGroup
int COptions::populateListWidget(QListWidget *listOfProfileInCombo,QString dirname,QString profilename)
{
    int found = 0;
    int compt = 0;
    listOfProfileInCombo->clear();
    foreach( QString key, this->hashProfileGroup.keys() )
    {
        QListWidgetItem *item = new QListWidgetItem(key);
        item->setFlags(Qt::ItemIsSelectable);
        QFont font = item->font();
        font.setBold(true);
        item->setFont(font);
        // TODO
        //
        QString iconFile = this->profileDir + "/" + key + ".png";
        QString defaultIconFile = this->profileDir + "/group.png";
        if ( QFileInfo(iconFile).exists() )
            item->setIcon(QIcon(iconFile));
        else if ( QFileInfo(defaultIconFile).exists() )
            item->setIcon(QIcon(defaultIconFile));

        listOfProfileInCombo->addItem(item);
        compt++;
        foreach(CProfile *pf, this->hashProfileGroup[key]){
            if ( QDir::cleanPath(pf->filename) == QDir::cleanPath(profilename) &&
                 QDir::cleanPath(pf->dirname) == QDir::cleanPath(dirname))
                found = compt;
            QListWidgetItem *w = new QListWidgetItem(this->settings->value("descPrefix",descPrefixConst).toString() + pf->description);
                            QString profileFile = pf->dirname+ "/" + pf->filename;
                            if ( ! QFile(profileFile).exists())
                                w->setTextColor(QColor(204,51,51));

            listOfProfileInCombo->addItem(w);
            compt++;
        }
    }
    listOfProfileInCombo->update();
    return found;
}

void COptions::populateComboBox(QString profileDirName,QString profileFileName,
                                QListWidget *listOfProfileInCombo,QString dirname,QString filename)
{
    populateComboBox(m_ui->defaultProfileComboBox,
                     profileDirName,
                     profileFileName,
                     listOfProfileInCombo,
                     dirname,
                     filename);
}

void COptions::populateComboBox(QComboBox *combo,QString profileDirName,QString profileFileName,
                                QListWidget *listOfProfileInCombo,QString dirname,QString filename)
{
    this->populateListWidget(listOfProfileInCombo,dirname,filename);
    combo->setModel(listOfProfileInCombo->model());
    combo->setView(listOfProfileInCombo);

    int ind = this->getIndexOfProfileInComboBox(profileDirName, profileFileName);
    combo->setCurrentIndex(ind);
}
